| |
3.2. Адресація операндів
Велика частина команд процесора працює з кодами даних (операндами). Одні команди вимагають вхідних операндів (одного або двох), інші видають вихідні операнди (частіше один операнд). Вхідні операнди називаються ще операндами-джерелами, а вихідні називаються операндами-приймачами. Всі ці коди операндів (вхідні і вихідні) повинні десь розташовуватися. Вони можуть знаходитися у внутрішніх регістрах процесора (найзручніший і швидкий варіант). Вони можуть розташовуватися в системній пам'яті (найпоширеніший варіант). Нарешті, вони можуть знаходитися в пристроях вводу/виводу (самий окремий випадок). Визначення місця положення операндів проводиться кодом команди. Причому існують різні методи, за допомогою яких код команди може визначити, звідки брати вхідний операнд і куди поміщати вихідний операнд. Ці методи називаються методами адресації. Ефективність вибраних методів адресації багато в чому визначає ефективність роботи всього процесора в цілому.
3.2.1. Методи адресації
Кількість методів адресації в різних процесорах може бути від 4 до 16. Розглянемо декілька типових методів адресації операндів, що використовуються зараз в більшості мікропроцесорів.
Безпосередня адресація (мал. 3.1) припускає, що операнд (вхідний) знаходиться в пам'яті безпосередньо за кодом команди. Операнд звичайно є константою, яку треба кудись переслати, до чогось додати і т.д. Наприклад, команда може полягати в тому, щоб додати число 6 до вмісту якогось внутрішнього регістра процесора. Це число 6 розташовуватиметься в пам'яті, усередині програми в адресі, наступній за кодом даної команди складання.

Мал. 3.1. Безпосередня адресація.
Пряма (вона ж абсолютна) адресація (мал. 3.2) припускає, що операнд (вхідний або вихідний) знаходиться в пам'яті за адресою, код якого знаходиться усередині програми зразу ж за кодом команди. Наприклад, команда може полягати в тому, щоб очистити (зробити нульовим) вміст елемента пам'яті з адресою 1000000. Код цієї адреси 1000000 розташовуватиметься в пам'яті, усередині програми в наступній адресі за кодом даної команди очищення.

Мал. 3.2. Пряма адресація.
Регістрова адресація (мал. 3.3) припускає, що операнд (вхідний або вихідний) знаходиться у внутрішньому регістрі процесора. Наприклад, команда може полягати в тому, щоб переслати число з нульового регістра в перший. Номери обох регістрів (0 і 1) визначатимуться кодом команди пересилки.
Непрямо-регістрова (вона ж непряма) адресація припускає, що у внутрішньому регістрі процесора знаходиться не сам операнд, а його адреса в пам'яті (мал. 3.4). Наприклад, команда може полягати в тому, щоб очистити елемент пам'яті з адресою, що знаходиться в нульовому регістрі. Номер цього регістра (0) визначатиметься кодом команди очищення.

Мал. 3.3. Регістрова адресація.

Мал. 3.4. Непряма адресація.
Рідше зустрічаються ще два методи адресації.
Автоінкрементна адресація дуже близька до непрямої адресації, але відрізняється від неї тим, що після виконання команди вміст регістра, що використовується, збільшується на одиницю або на два. Цей метод адресації дуже зручний, наприклад, при послідовній обробці кодів з масиву даних, що знаходиться в пам'яті. Після обробки якогось коду адреса в регістрі указуватиме вже на наступний код з масиву. При використовуванні непрямої адресації в даному випадку довелося б збільшувати вміст цього регістра окремою командою.
Автодекрементна адресація працює схоже на автоінкрементну, але тільки вміст вибраного регістра зменшується на одиницю або на два перед виконанням команди. Ця адресація також зручна при обробці масивів даних. Сумісне використовування автоінкрементної і автодекрементної адресацій дозволяє організувати пам'ять стекового типу (див. розділ 2.4.2).
З інших поширених методів адресації можна згадати про індексні методи, які припускають для обчислення адреси операнда надбавку до вмісту регістра заданої константи (індексу). Код цієї константи розташовується в пам'яті безпосередньо за кодом команди.
Відзначимо, що вибір того або іншого методу адресації в значній мірі визначає час виконання команди. Найшвидша адресація - це регістрова, оскільки вона не вимагає додаткових циклів обміну по магістралі. Якщо ж адресація вимагає звернення до пам'яті, то час виконання команди збільшуватиметься за рахунок тривалості необхідних циклів звернення до пам'яті. Зрозуміло, що чим більше внутрішніх регістрів у процесора, тим частіше і вільніше можна застосовувати регістрову адресацію, і тим швидше працювати система в цілому.
3.2.2. Сегментація пам'яті
Кажучи про адресацію, не можна обійти питання про сегментацію пам'яті, вживаної в деяких процесорах, наприклад в процесорах IBM PC-сумісних персональних комп'ютерів.
В процесорі Intel 8086 сегментація пам'яті організована таким чином.
Вся пам'ять системи представляється не у вигляді безперервного простору, а у вигляді декількох областей - сегментів заданого розміру (по 64 Кбайта), положення яких в просторі пам'яті можна змінювати програмним шляхом.
Для зберігання кодів адрес пам'яті використовуються не окремі регістри, а пари регістрів:
- сегментний регістр визначає адресу початку сегменту (тобто положення сегменту в пам'яті);
- регістр покажчика (регістр зсуву) визначає положення робочої адреси усередині сегменту.
При цьому фізична 20-розрядна адреса пам'яті, що виставляється на зовнішню шину адреси, утворюється так, як показано на мал. 3.5, тобто шляхом складання зсуву і адреси сегменту із зсувом на 4 біти. Положення цієї адреси в пам'яті показано на мал. 3.6.
Сегмент може починатися тільки на 16-байтній межі пам'яті (оскільки адреса початку сегменту, по суті, має чотири молодші нульові розряди, як видно з мал. 3.5), тобто з адреси, кратної 16. Ці допустимі межі сегментів називаються межами параграфів.
Відзначимо, що введення сегментації, перш за все, зв'язано з тим, що внутрішні регістри процесора 16-розрядні, а фізична адреса пам'яті 20-розрядна (16-розрядна адреса дозволяє використовувати пам'ять тільки в 64 Кбайт, що явно недостатньо). В процесорі MC68000 фірми Motorola , що з'явився в той же час, внутрішні регістри 32-розрядні, тому там проблеми сегментації пам'яті не виникає.

Мал. 3.5. Формування фізичної адреси пам'яті з адреси сегменту і зсуву.

Мал. 3.6. Фізична адреса в сегменті (всі коди - шістнадцяткові).
Застосовуються і складніші методи сегментації пам'яті. Наприклад, в процесорі Intel 80286 в так званому захищеному режимі адреса пам'яті обчислюється відповідно до мал. 3.7.
В сегментному регістрі в даному випадку зберігається не базова (початкова) адреса сегментів, а коди селекторів, що визначають адреси в пам'яті, по яких зберігаються дескриптори (тобто описувачі) сегментів. Область пам'яті з дескрипторами називається таблицею дескрипторів. Кожний дескриптор сегменту містить базову адресу сегменту, розмір сегменту (від 1 до 64 Кбайт) і його атрибути. Базова адреса сегменту має розрядність 24 біт, що забезпечує адресацію 16 Мбайт фізичної пам'яті.

Мал. 3.7. Адресація пам'яті в захищеному режимі процесора Intel 80286.
Таким чином, на суматор, що обчислює фізичну адресу пам'яті, подається не вміст сегментного регістра, як у попередньому випадку, а базова адреса сегменту з таблиці дескрипторів.
Ще складніший метод адресації пам'яті з сегментацією використаний в процесорі Intel 80386 і в більш пізніх моделях процесорів фірми Intel. Цей метод ілюструється мал. 3.8.
Адреса пам'яті (фізична адреса) обчислюється в три етапи. Спочатку обчислюється так звана ефективна адреса (32-розрядний) шляхом підсумовування трьох компонентів: бази, індексу і зсуву (Base, Index, Displacement), причому можливе множення індексу на масштаб (Scale). Ці компоненти мають наступний сенс:

Мал. 3.8. Формування фізичної адреси пам'яті процесора 80386 в захищеному режимі.
- зсув - це 8-, 16- або 32-розрядне число, включене в команду.
- база - цей вміст базового регістра процесора. Звичайно воно використовується для вказівки на початок деякого масиву.
- індекс - цей вміст індексного регістра процесора. Звичайно воно використовується для вибору одного з елементів масиву.
- масштаб - це множник (він може бути рівний 1, 2, 4 або 8), вказаний в коді команди, на який перед підсумовуванням з іншими компонентами умножається індекс. Він використовується для вказівки розміру елемента масиву.
Потім спеціальний блок сегментації обчислює 32-розрядну лінійну адресу, яка є сумою базової адреси сегменту з сегментного регістра з ефективною адресою. Нарешті, фізична 32-бітова адреса пам'яті утворюється шляхом перетворення лінійної адреси блоком сторінкової переадресації, який здійснює переклад лінійної адреси у фізичний сторінками по 4 Кбайта.
У будь-якому випадку сегментація дозволяє виділити в пам'яті один або декілька сегментів для даних і один або декілька сегментів для програм. Перехід від одного сегменту до іншого зводиться всього лише до зміни вмісту сегментного регістра. Іноді це дуже зручно. Але для програміста працювати з сегментованою пам'яттю звичайно складніше, ніж з безперервною, несегментованою пам'яттю, оскільки доводиться стежити за межами сегментів, за їх описом, перемиканням і т.д.
3.2.3. Адресація байт і слів
Багато процесорів, що мають розрядність 16 або 32, здатні адресувати не тільки ціле слово в пам'яті (16-розрядне або 32-розрядне), але і окремі байти. Кожному байту в кожному слові при цьому відводиться своя адреса.
Так, у разі 16-розрядних процесорів всі слова в пам'яті (16-розрядні) мають парні адреси. А байти, що входять в ці слова, можуть мати як парні адреси, так і непарні.
Наприклад, нехай 16-розрядний елемент пам'яті має адресу 23420, і в ній зберігається код 2А5Е (мал. 3.9 ).

Мал. 3.9. Адресація слів і байтів.
При зверненні до цілого слова (з вмістом 2А5Е) процесор виставляє адресу 23420. При зверненні до молодшого байта цієї комірки (з вмістом 5Е) процесор виставляє ту ж саму адресу 23420, але використовує команду, що адресує байт, а не слово. При зверненні до старшого байта цієї комірки (з вмістом 2А) процесор виставляє адресу 23421 і використовує команду, що адресує байт. Наступний по порядку 16-розрядний елемент пам'яті з вмістом 487F матиме адресу 23422, тобто знову ж таки парний. Її байти матимуть адреси 23422 і 23423.
Для розрізення байтових і словних циклів обміну на магістралі в шині управління передбачається спеціальний сигнал байтового обміну. Для роботи з байтами в систему команд процесора вводяться спеціальні команди або передбачаються методи байтової адресації.
попередня тема наступна тема
|